package com.hhd.flow.controller;

import com.alibaba.fastjson.JSONObject;
import com.hhd.flow.vo.ProcessInstancePath;
import com.hhd.flow.vo.Result;
import com.hhd.flow.engine.FlowEngine;
import com.hhd.flow.engine.utils.CommonUtils;
import com.hhd.flow.entity.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/flow")
public class HistoryController {
    @Autowired
    FlowEngine flowEngine;

    @GetMapping("/getFlowModeByProcessInstanceId")
    public Result getFlowModeByProcessInstanceId(String processInstanceId) {
        FlowProcessInstance flowProcessInstance = getFlowProcessInstance(processInstanceId);
        if (CommonUtils.isEmpty(flowProcessInstance)) {
            flowProcessInstance = CommonUtils.copyTo(flowEngine.getFlowProcessInstanceHistoryService().getById(processInstanceId), FlowProcessInstance.class);
        }
        String model = flowProcessInstance.getModel();
        if (!CommonUtils.isEmpty(model)) {
            return Result.ok(JSONObject.parse(model));
        }
        FlowProcessDefinitionRef ref = flowEngine.getFlowProcessDefinitionRefService().getById(flowProcessInstance.getProcessDefinitionId());
        return Result.ok(JSONObject.parse(ref.getModel()));
    }

    private FlowProcessInstance getFlowProcessInstance(String processInstanceId) {
        FlowProcessInstance flowProcessInstance = flowEngine.getFlowProcessInstanceService().getById(processInstanceId);
        if (CommonUtils.isEmpty(flowEngine)) {
            FlowProcessInstanceHistory history = flowEngine.getFlowProcessInstanceHistoryService().getById(processInstanceId);
            flowProcessInstance = CommonUtils.copyTo(history, FlowProcessInstance.class);
        }
        return flowProcessInstance;
    }

    @GetMapping("/getProcessInstancePath")
    public Result getProcessInstancePath(String processInstanceId) {
        List<FlowPath> list = flowEngine.getFlowPathService().lambdaQuery().eq(FlowPath::getProcessInstanceId, processInstanceId).list();
        if (CommonUtils.isEmpty(list)) return Result.ok(new ProcessInstancePath());

        ProcessInstancePath processInstancePath = new ProcessInstancePath();
        FlowPath flowPath = list.get(0);

        String[] split = flowPath.getPath().split(",");
        Set<String> pathSet = Arrays.stream(split).collect(Collectors.toSet());

        List<FlowTask> flowTasks = flowEngine.getFlowTaskService().lambdaQuery()
                .eq(FlowTask::getProcessInstanceId, processInstanceId)
                .list();
        for (FlowTask flowTask : flowTasks) {
            pathSet.remove(flowTask.getTaskDefinitionId());
        }

        processInstancePath.setHistoryNodeList(new LinkedList(pathSet));
        processInstancePath.setCurrentNodeList(flowTasks.stream().map(FlowTask::getTaskDefinitionId).collect(Collectors.toList()));
        processInstancePath.setFlowNodeStop(flowPath.getEndId());
        return Result.ok(processInstancePath);
    }

    @GetMapping("/getUserTaskHistoryByFormId")
    public Result getUserTaskHistoryByFormId(String formId) {
        JSONObject jsonObject = new JSONObject();
        List<FlowUserTask> list = flowEngine.getFlowUserTaskService().lambdaQuery()
                .eq(FlowUserTask::getFormId, formId)
                .list();
        for (FlowUserTask flowUserTask : list) {
            if ("[]".equals(flowUserTask.getUserSign())) {
                flowUserTask.setUserSign(null);
            }
        }
        List<FlowComment> list1 = flowEngine.getFlowCommentService().lambdaQuery()
                .eq(FlowComment::getFormId, formId)
                .list();
        for (FlowComment flowUserTask : list1) {
            if ("[]".equals(flowUserTask.getUserSign())) {
                flowUserTask.setUserSign(null);
            }
        }
        jsonObject.put("current", list); //待办
        jsonObject.put("history", list1); //已办
        return Result.ok(jsonObject);
    }

    @GetMapping("/getUserTaskHistory")
    public Result getUserTaskHistory(String processInstanceId, String taskDefinitionId) {
        JSONObject jsonObject = new JSONObject();
        List<FlowUserTask> list = flowEngine.getFlowUserTaskService().lambdaQuery()
                .eq(FlowUserTask::getProcessInstanceId, processInstanceId)
                .eq(FlowUserTask::getTaskDefinitionId, taskDefinitionId)
                .list();
        for (FlowUserTask flowUserTask : list) {
            if ("[]".equals(flowUserTask.getUserSign())) {
                flowUserTask.setUserSign(null);
            }
        }

        List<FlowComment> list1 = flowEngine.getFlowCommentService().lambdaQuery()
                .eq(FlowComment::getProcessInstanceId, processInstanceId)
                .eq(FlowComment::getTaskDefinitionId, taskDefinitionId)
                .list();
        for (FlowComment flowUserTask : list1) {
            if ("[]".equals(flowUserTask.getUserSign())) {
                flowUserTask.setUserSign(null);
            }
        }
        jsonObject.put("current", list); //待办
        jsonObject.put("history", list1); //已办
        return Result.ok(jsonObject);
    }
}
